home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / bin / findaffix < prev    next >
Text File  |  2009-10-02  |  10KB  |  297 lines

  1. #! /bin/sh
  2. #
  3. # $Id: findaffix.X,v 1.15 1994/01/25 07:11:29 geoff Exp $
  4. #
  5. # Copyright 1992, 1993, Geoff Kuenning, Granada Hills, CA
  6. # All rights reserved.
  7. #
  8. # Redistribution and use in source and binary forms, with or without
  9. # modification, are permitted provided that the following conditions
  10. # are met:
  11. #
  12. # 1. Redistributions of source code must retain the above copyright
  13. #    notice, this list of conditions and the following disclaimer.
  14. # 2. Redistributions in binary form must reproduce the above copyright
  15. #    notice, this list of conditions and the following disclaimer in the
  16. #    documentation and/or other materials provided with the distribution.
  17. # 3. All modifications to the source code must be clearly marked as
  18. #    such.  Binary redistributions based on modified source code
  19. #    must be clearly marked as modified versions in the documentation
  20. #    and/or other materials provided with the distribution.
  21. # 4. All advertising materials mentioning features or use of this software
  22. #    must display the following acknowledgment:
  23. #      This product includes software developed by Geoff Kuenning and
  24. #      other unpaid contributors.
  25. # 5. The name of Geoff Kuenning may not be used to endorse or promote
  26. #    products derived from this software without specific prior
  27. #    written permission.
  28. #
  29. # THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
  30. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  31. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  32. # ARE DISCLAIMED.  IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
  33. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  34. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  35. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  36. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  37. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  38. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  39. # SUCH DAMAGE.
  40. #
  41. #    Find possible affixes for use with ispell
  42. #
  43. #    Usage:
  44. #
  45. #    findaffix [-p | -s] [-f] [-c] [-m min] [-M max] [-e elim] [-l low] \
  46. #      [-t tabchar] [files]
  47. #
  48. #    Each common prefix (-p) or suffix (-s, default) is presented, along
  49. #    with statistics to indicate how useful such an affix might be in
  50. #    reducing the size of the input file.  Only those affixes which
  51. #    produce a legal root (one found in the original input) are reported.
  52. #
  53. #    If the "-c" option is not given, the output lines are in the
  54. #    following format:
  55. #
  56. #        strip/add/count/bytes
  57. #
  58. #    where "strip" is the string that should be stripped from a root
  59. #    word before adding the affix, "add" is the affix to be added, "count"
  60. #    is a count of the number of times that this "strip/add" combination
  61. #    appears, and "bytes" is an estimate of the number of bytes that
  62. #    will be saved in the raw dictionary file if this combination is
  63. #    added to the affix file.  The field separator in the output will
  64. #    normally be the tab character specified by the "-t" switch;  the
  65. #    default is a slash ("/").
  66. #
  67. #    If the "-c" ("clean output") option is given, the appearance of
  68. #    the output is made cleaner by changing it to:
  69. #
  70. #        -strip+add<tab>count<tab>bytes
  71. #
  72. #    where "strip," "add," "count," and "bytes" are as before, and "<tab>"
  73. #    represents the ASCII tab character.
  74. #
  75. #    The method used to generate possible affixes will also generate
  76. #    longer affixes which have common headers or trailers.  For example,
  77. #    the two words "moth" and "mother" will generate not only the obvious
  78. #    substition "+er" but also "-h+her" and "-th+ther" (and possibly
  79. #    even longer ones, depending on the value of "min").  To prevent
  80. #    cluttering the output with such affixes, any affix pair that shares
  81. #    a common header (or, for prefixes, trailer) string longer than
  82. #    "elim" characters (default 1) will be suppressed.  You may want to
  83. #    set "elim" to a value greater than 1 if your language has string
  84. #    characters;  usually the need for this parameter will become obvious
  85. #    when you examine the output of your findaffix run.
  86. #
  87. #    Normally, the output is sorted on the "bytes" field.  If the "-f"
  88. #    flag is given, the output is sorted according to the "count" field.
  89. #
  90. #    No affix longer than "max" characters (default 8) will be reported.
  91. #    Smaller values of "max" will make the script run faster.
  92. #
  93. #    Affixes which appear fewer than "low" times (default 10) are
  94. #    suppressed.  This significantly reduces the size of the output file.
  95. #
  96. #    Affixes which generate stems shorter than "min" characters (default 3)
  97. #    are suppressed.  (A stem is the word after the "strip" string has
  98. #    been removed, and before the "add" string has been added.)  This
  99. #    reduces both the running time and the size of the output file.  "Min"
  100. #    should only be set to 1 if you have a *lot* of free time and disk
  101. #    space.
  102. #
  103. #    The script requires a non-blank field-separator character for internal
  104. #    use.  Normally, this character is a slash ("/"), but if the slash
  105. #    appears as a character in the input word list, a different character
  106. #    can be specified with the "-t" switch.
  107. #
  108. #    If the input files are ispell dictionaries, they should be expanded
  109. #    before being fed to this script.
  110. #
  111. #    If the input files contains characters other than [A-Za-z], they
  112. #    should be translated to lowercase before being fed to this script.
  113. #
  114. # $Log: findaffix.X,v $
  115. # Revision 1.15  1994/01/25  07:11:29  geoff
  116. # Get rid of all old RCS log lines in preparation for the 3.1 release.
  117. #
  118. #
  119. TDIR=${TMPDIR-/tmp}
  120. SORTTMP="-T ${TDIR}"            # !!SORTTMP!!
  121. USAGE='Usage:  findaffix [-p | -s] [-f] [-c] [-e elim] [-m min] [-M max] [-l low] [-t tabch] [files]'
  122. LOOP='
  123.     i = len - maxlim + 1
  124.     if (i < minstem + 1)
  125.     i = minstem + 1
  126.     for (  ;  i <= len;  i++)
  127.     print substr ($0, 1, i - 1) tabch substr ($0, i) tabch len
  128.     print $0 tabch tabch len'
  129. ELIM='$1!=$2 \
  130.     {
  131.     if (substr ($1, 1, elimlen) != substr ($2, 1, elimlen))
  132.     print
  133.     }'
  134. maxlim=8
  135. minstem=3
  136. elimlen=1
  137. lowcount=10
  138. cleanout=no
  139. finalsortopts='+3rn -4 +2rn -3 +1 -2 +0 -1'
  140. tabch=/
  141. while :
  142. do
  143.     case "$1" in
  144.     -p)
  145.         LOOP='
  146.         lim = len - minstem
  147.         if (lim > maxlim)
  148.             lim = maxlim
  149.         for (i = 1;  i <= lim;  i++)
  150.             print substr ($0, i + 1) tabch substr ($0, 1, i) tabch len
  151.         print $0 tabch tabch len'
  152.         ELIM='$1!=$2 \
  153.         {
  154.         if (substr ($1, length ($1), elimlen) \
  155.           != substr ($2, length ($2), elimlen))
  156.             print
  157.         }'
  158.         shift
  159.         ;;
  160.     -s)
  161.         shift
  162.         ;;
  163.     -f)
  164.         finalsortopts='+2rn -3 +3rn -4 +1 -2 +0 -1'
  165.         shift
  166.         ;;
  167.     -c)
  168.         cleanout=yes
  169.         shift
  170.         ;;
  171.     -e)
  172.         elimlen=$2
  173.         shift; shift
  174.         ;;
  175.     -m)
  176.         minstem=$2
  177.         shift; shift
  178.         ;;
  179.     -M)
  180.         maxlim=$2
  181.         shift; shift
  182.         ;;
  183.     -l)
  184.         lowcount=$2
  185.         shift; shift
  186.         ;;
  187.     -t)
  188.         tabch="$2"
  189.         shift; shift
  190.         ;;
  191.     -*)
  192.         echo "$USAGE" 1>&2
  193.         exit 1
  194.         ;;
  195.     *)
  196.         break
  197.         ;;
  198.     esac
  199. done
  200. TMPFILE=`mktemp -q ${TDIR}/findaffix.XXXXXX`
  201.     if [ $? -ne 0 ]; then
  202.         echo "$0: Can't create temp file, exiting..."
  203.         exit 1
  204.     fi
  205. trap "/bin/rm -f ${TMPFILE}; exit 1" 1 2 15
  206. trap "/bin/rm -f ${TMPFILE}; exit 0" 13
  207. #
  208. # We are ready to do the work.  First, we collect all input, translate it
  209. # to lowercase, sort it (dropping duplications), and save it for later.
  210. #
  211. if [ $# -ne 0 ]
  212. then
  213.     cat "$@" | tr '[A-Z]' '[a-z]'
  214. else
  215.     tr '[A-Z]' '[a-z]'
  216. fi \
  217.   | sort -u $SORTTMP > ${TMPFILE}
  218. #
  219. # Now the monstrous pipeline.  The awk command produces several lines for
  220. # each input word.  Each line contains a possible stem (first field),
  221. # a possible affix, and the length of the original word.  The loop which
  222. # does this was placed into the LOOP variable by the code above (q.v.).
  223. #
  224. # The first sort puts this output into an order appropriate for feeding
  225. # to 'join'.  The join command then combines stems and affixes, and for
  226. # each puts out an affix to strip, an affix to add, and the length of
  227. # the word before and after modification.
  228. #
  229. # From here on out the job is relatively easy.  The second 'awk' gets rid
  230. # of lines that have the same strip and add affixes, and also eliminates
  231. # lines where the strip and add affix have a common leading (for suffixes)
  232. # or trailing (for prefixes) substring, or where the strip affix is longer
  233. # than the add affix (this is all done by the $ELIM variable, which is also
  234. # set up by the code above.  The second sort collects identical affixes;
  235. # the third 'awk' functions like 'uniq -c', replacing duplicate affixes
  236. # with a count and summing the estimate of bytes saved.  It also eliminates
  237. # any affixes which appear less frequently than the minimum ("lowcount").
  238. # Finally, the third sort ($finalsortopts) rearranges the list in the chosen
  239. # sort order.
  240. #
  241. awk "BEGIN{minstem=$minstem; maxlim=$maxlim; tabch="'"'"$tabch"'"}
  242.     {
  243.     len = length ($0)
  244.     if (len < 2)
  245.     next
  246.     '"$LOOP"'
  247.     }' < ${TMPFILE} \
  248.   | sort "-t$tabch" +0 -1 +1 $SORTTMP -o ${TMPFILE}
  249. join "-t$tabch" -o 1.2 2.2 2.3 ${TMPFILE} ${TMPFILE} \
  250.   | awk "-F$tabch" "BEGIN{elimlen=$elimlen}$ELIM" \
  251.   | sort "-t$tabch" +1 -2 +0 -1 $SORTTMP \
  252.   | awk "-F$tabch" 'BEGIN{tabch="'"$tabch"'"; lowcount='"$lowcount"'}
  253.     {
  254.     if ($1 == last1  &&  $2 == last2)
  255.         {
  256.         count++
  257.         totchars += $3
  258.         }
  259.     else
  260.         {
  261.         if ((last1 != ""  ||  last2 != "")  &&  count >= lowcount)
  262.         print last1 tabch last2 tabch count tabch totchars
  263.         count = 1
  264.         last1 = $1
  265.         last2 = $2
  266.         totchars = $3
  267.         }
  268.     }
  269.     END {
  270.     if ((last1 != ""  ||  last2 != "")  &&  count >= lowcount)
  271.         print last1 tabch last2 tabch count tabch totchars
  272.     }' \
  273.   | sort "-t$tabch" $finalsortopts $SORTTMP \
  274.   | if [ "$cleanout" = "yes" ]
  275.     then
  276.     case "$tabch" in
  277.         /)
  278.         sedsub=/
  279.         sedsep=';'
  280.         ;;
  281.         .|\*|\[|\^|\$|\\)
  282.         sedsub="\\$tabch"
  283.         sedsep=/
  284.         ;;
  285.         *)
  286.         sedsub="$tabch"
  287.         sedsep=/
  288.         ;;
  289.     esac
  290.     exec sed -e "s$sedsep$sedsub$sedsep    ${sedsep}g" \
  291.       -e 's/    /+/' -e 's/^/-/' \
  292.       -e 's/^-+/+/' -e 's/+    /    /'
  293.     else
  294.     exec cat
  295.     fi
  296. /bin/rm -f ${TMPFILE}
  297.